package com.youhui.weixin.utils.excel;

import com.youhui.weixin.common.MythConfig;
import com.youhui.weixin.common.exception.LoadFileException;
import com.youhui.weixin.dao.TypesDao;
import com.youhui.weixin.domain.Types;
import com.youhui.weixin.utils.PropertiesLoad;
import lombok.extern.log4j.Log4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.HashOperations;
import org.springframework.data.redis.core.SetOperations;
import org.springframework.data.redis.core.StringRedisTemplate;
import org.springframework.data.redis.core.ZSetOperations;
import org.springframework.stereotype.Component;

import java.io.UnsupportedEncodingException;
import java.util.*;

import static com.youhui.weixin.common.MythConfig.*;

/**
 * properties文件读取的时候，编码问题一定要注意
 */
@Log4j
@Component
public class DealType {

    @Autowired
    private StringRedisTemplate stringRedisTemplate;
    @Autowired
    TypesDao typesDao;

    private HashOperations<String, String, String> hash=null;
    private ZSetOperations<String, String> zset;
    private SetOperations<String, String> set;
    private Map<String, String> typeDict;
    private Map<String, String> typeMapping;
    private Set<String> typeOrder;
    private Set<String> typeIgnore;

    /**
     * 清除该Bean得到的redis数据，不然的话内存中的数据一直是旧数据了
     */
    public void flushMapCache(){
        if(typeDict!=null) typeDict.clear();
        if(typeMapping!=null) typeMapping.clear();
        if(typeOrder!=null) typeOrder.clear();
        if(typeIgnore!=null) typeIgnore.clear();
    }

    /**
     * 长链接处理
     * @return 短链接
     */
    public String handleLink(Long goodsId, String originLink){
        if(hash == null) hash = stringRedisTemplate.opsForHash();
        String shortLink = longTurnShort(originLink);
        hash.put(SHORT_MAP, shortLink, originLink);
        hash.put(SHORT_INDEX, goodsId+"", shortLink);
        return MythConfig.SHORT_LINK+shortLink;
    }
    /**
     * 逻辑：读取redis中存储的关键字分类，进行匹配，然后得到分类id（分类id也放在redis中）
     * 处理商品名，得到分类的id
     * @param goodsName 商品名
     * @return 分类id，匹配不到就返回0
     */
    public int handle(String goodsName) throws LoadFileException, UnsupportedEncodingException {
        if(hash == null) hash = stringRedisTemplate.opsForHash();
        if(zset == null) zset = stringRedisTemplate.opsForZSet();
        if(set == null) set = stringRedisTemplate.opsForSet();
        checkData();
        return handleTypeByName(goodsName);
    }
    /** 真正处理分类的数据的函数
     */
    private int handleTypeByName(String goodsName){

        int typeId;
        if (goodsName.contains("男")) {
            typeId = isInType("男装", goodsName);
            if (typeId != 0) {
                return typeId;
            } else {
                typeId = isInType("男鞋", goodsName);
                if (typeId != 0) {
                    return typeId;
                }
            }
        } else if (goodsName.contains("女") || goodsName.contains("裙")) {
            typeId = isInType("女装", goodsName);
            if (typeId != 0) {
                return typeId;
            } else {
                typeId = isInType("女鞋", goodsName);
                if (typeId != 0) {
                    return typeId;
                }
            }
        }
        // 循环剩余的分类 有序性的
        for(String type: typeOrder){
            typeId = isInType(type, goodsName);
            if (typeId != 0) {
                return typeId;
            }
        }
        return NO_TYPE_ID;
    }
    /**
     * 判断redis中是否具有对应的数据，如果没有就进行装载初始化 基础方法
     * @throws LoadFileException 各种可能的异常。。。
     */
    private void checkData() throws LoadFileException, UnsupportedEncodingException {
        //配置文件和Mysql加载到redis里
        boolean flagMapping = stringRedisTemplate.hasKey(TYPE_MAPPING);
        if (!flagMapping){
            List<Types> lists = typesDao.findAll();
            for (Types type : lists) {
                hash.put(TYPE_MAPPING, type.getName(), type.getTypeId() + "");
            }
        }
        boolean flagDict = stringRedisTemplate.hasKey(TYPE_DICT);
        if(!flagDict){
            Properties typeConfig = PropertiesLoad.loadConfig(MythConfig.TYPE_INIT_PROPERTIES);
            Set typeLine = typeConfig.keySet();
            for (Object object : typeLine) {
                String content = typeConfig.getProperty(object.toString());
                content = new String(content.getBytes("iso8859-1"), "utf-8");
                String name = new String(object.toString().getBytes("iso8859-1"), "utf-8");
                hash.put(TYPE_DICT, content, name);
            }
        }
        // redis 加载到内存里
        if (typeDict == null || typeDict.size() == 0) {
            typeDict = hash.entries(TYPE_DICT);
        }
        if (typeMapping == null || typeMapping.size() == 0) {
            typeMapping = hash.entries(TYPE_MAPPING);
        }
        if(typeOrder == null || typeOrder.size() == 0){
            typeOrder = zset.range(TYPE_ORDERED, TYPE_ORDERED_MIN,TYPE_ORDERED_MAX);
        }
        if(typeIgnore == null || typeIgnore.size() == 0){
            typeIgnore = set.members(TYPE_IGNORE_WORD);
        }
    }

    /** 获取id的方法
     */
    private int isInType(String typeName, String goodsName) {
//        log.info(goodsName+" 分类 "+typeName);
        String type_values = typeDict.get(typeName);
        for(String key:typeIgnore){
            goodsName = goodsName.replace(key, "");
        }
        String[] tempKeys = type_values.split(TYPE_SPACE);
        for (String key : tempKeys) {
            if (goodsName.contains(key)) {
                String result = typeMapping.get(typeName);
                return Integer.valueOf(result);
            }
        }
        return 0;
    }

    /**
     * 处理链接转换
     * @param originLink 原始长链接
     * @return uuid
     */
    private String longTurnShort(String originLink){
//        return String.valueOf(UUID.nameUUIDFromBytes(originLink.getBytes()).toString().hashCode());
        return UUID.nameUUIDFromBytes(originLink.getBytes()).toString().replace("-","0");
    }

}
